package cn.iocoder.an.module.business.service.equipmentmanage;

import cn.hutool.core.collection.CollUtil;
import cn.iocoder.an.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.an.module.business.dal.dataobject.equipmenttype.EquipmentTypeDO;
import cn.iocoder.an.module.business.dal.dataobject.maintenanceclassification.MaintenanceClassificationDO;
import cn.iocoder.an.module.business.service.equipmenttype.EquipmentTypeService;
import cn.iocoder.an.module.system.dal.dataobject.dept.DeptDO;
import cn.iocoder.an.module.system.dal.dataobject.user.AdminUserDO;
import cn.iocoder.an.module.system.service.dept.DeptService;
import cn.iocoder.an.module.system.service.user.AdminUserService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import io.micrometer.common.util.StringUtils;
import org.springframework.stereotype.Service;
import jakarta.annotation.Resource;
import org.springframework.validation.annotation.Validated;

import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

import cn.iocoder.an.module.business.controller.admin.equipmentmanage.vo.*;
import cn.iocoder.an.module.business.dal.dataobject.equipmentmanage.EquipmentManageDO;
import cn.iocoder.an.framework.common.pojo.PageResult;
import cn.iocoder.an.framework.common.util.object.BeanUtils;

import cn.iocoder.an.module.business.dal.mysql.equipmentmanage.EquipmentManageMapper;

import static cn.iocoder.an.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.an.framework.common.util.collection.CollectionUtils.convertList;
import static cn.iocoder.an.module.business.enums.ErrorCodeConstants.*;

/**
 * 设备台账 Service 实现类
 *
 * @author zzy
 */
@Service
@Validated
public class EquipmentManageServiceImpl implements EquipmentManageService {

    @Resource
    private EquipmentManageMapper equipmentManageMapper;

    @Resource
    private DeptService deptService;

    @Resource
    private EquipmentTypeService equipmentTypeService;

    @Resource
    private AdminUserService userService;

    @Override
    public Long createEquipmentManage(EquipmentManageSaveReqVO createReqVO) {
        // 插入
        setReVOName(createReqVO);
        //查询编码是否已存在
        checkCodeExists(createReqVO);
        EquipmentManageDO equipmentManage = BeanUtils.toBean(createReqVO, EquipmentManageDO.class);
        setUserName(equipmentManage);
        equipmentManageMapper.insert(equipmentManage);

        // 返回
        return equipmentManage.getId();
    }

    @Override
    public void updateEquipmentManage(EquipmentManageSaveReqVO updateReqVO) {
        // 校验存在
        validateEquipmentManageExists(updateReqVO.getId());
        setReVOName(updateReqVO);
        checkCodeExists(updateReqVO);
        // 更新
        EquipmentManageDO updateObj = BeanUtils.toBean(updateReqVO, EquipmentManageDO.class);
        setUserName(updateObj);
        equipmentManageMapper.updateById(updateObj);
    }

    //设备派工的更新
    @Override
    public void updateEquipmentManageByDo(EquipmentManageDO updateReqVO) {
        // 更新
        setUserName(updateReqVO);
        equipmentManageMapper.updateById(updateReqVO);
    }

    @Override
    public void deleteEquipmentManage(Long id) {
        // 校验存在
        validateEquipmentManageExists(id);
        // 删除
        equipmentManageMapper.deleteById(id);
    }

    @Override
    public void deleteEquipmentManageListByIds(List<Long> ids) {
        // 删除
        equipmentManageMapper.deleteByIds(ids);
    }


    private void validateEquipmentManageExists(Long id) {
        if (equipmentManageMapper.selectById(id) == null) {
            throw exception(EQUIPMENT_MANAGE_NOT_EXISTS);
        }
    }

    @Override
    public EquipmentManageDO getEquipmentManage(Long id) {
        return equipmentManageMapper.selectById(id);
    }

    @Override
    public PageResult<EquipmentManageDO> getEquipmentManagePage(EquipmentManagePageReqVO pageReqVO) {
        return equipmentManageMapper.selectPage(pageReqVO);
    }

    @Override
    public PageResult<EquipmentManageDO> getEquipmentManageCheckPage(EquipmentManagePageReqVO pageReqVO) {
        return equipmentManageMapper.selectCheckPage(pageReqVO);
    }

    @Override
    public List<EquipmentManageDO> getEquipmentManageList(String keyWords) {
        LambdaQueryWrapperX<EquipmentManageDO> wrapper = new LambdaQueryWrapperX<>();
        if (StringUtils.isNotBlank(keyWords)) {
            wrapper.and(i -> i
                    .like(EquipmentManageDO::getEquipmentName, keyWords)
                    .or().like(EquipmentManageDO::getCode, keyWords)
                    .or().like(EquipmentManageDO::getInstallPosition, keyWords)
            );
        }
        return equipmentManageMapper.selectList(wrapper);
    }

    @Override
    public ImportRespVO importEquipmentList(List<EquipmentImportExcelVO> importEquipment, boolean isUpdateSupport) {
        // 1.1 参数校验
        if (CollUtil.isEmpty(importEquipment)) {
            throw exception(IMPORT_EQUIPMENT_MANAGE_NOT_EXISTS);
        }
        //2.记录成功或失败记录
        ImportRespVO respVO = ImportRespVO.builder().insertNameList(new ArrayList<>())
                .updateNameList(new ArrayList<>()).failureMap(new LinkedHashMap<>()).build();

        AtomicInteger count = new AtomicInteger(1);
        importEquipment.forEach(equipment -> {
            count.incrementAndGet();//记录行号

            if (equipment.getEquipmentName() == null || equipment.getEquipmentName().trim().isEmpty()) {
                return;
            }

            // 2.1.1 校验设备编码
            if (StringUtils.isEmpty(equipment.getCode())) {
                respVO.getFailureMap().put(equipment.getEquipmentName(), "设备编码不能为空!");
                return;
            }

            // 2.1.2 校验设备名称
            if (StringUtils.isEmpty(equipment.getEquipmentName())) {
                respVO.getFailureMap().put(equipment.getEquipmentName(), "设备名称不能为空!");
                return;
            }

            // 2.1.3 校验所属部门
            if (StringUtils.isEmpty(equipment.getDeptName())) {
                respVO.getFailureMap().put(equipment.getEquipmentName(), "所属部门不能为空!");
                return;
            } else {
                //如果存在,使用部门名称查询部门ID,设置deptId
                try {
                    Long deptId = deptService.getDeptIdByDeptName(equipment.getDeptName());
                    equipment.setDeptId(deptId);
                } catch (Exception e) {
                    respVO.getFailureMap().put(equipment.getEquipmentName(), e.getMessage());
                    return;
                }
            }

            // 2.1.4 校验设备分类
            if (StringUtils.isEmpty(equipment.getEquipmentClassifyName())) {
                respVO.getFailureMap().put(equipment.getEquipmentName(), "设备分类不能为空!");
                return;
            } else {
                try {
                    Long equipmentTypeId = equipmentTypeService.getEquipmentTypeIdByName(equipment.getEquipmentClassifyName());
                    equipment.setEquipmentClassify(equipmentTypeId);
                } catch (Exception e) {
                    respVO.getFailureMap().put(equipment.getEquipmentName(), e.getMessage());
                    return;
                }
            }

            // 2.1.5 校验设备状态
            if (equipment.getEquipmentStatus() == null) {
                respVO.getFailureMap().put(equipment.getEquipmentName(), "设备状态不能为空");
                return;
            }

            // 2.2.6 判断是否存在，再进行更新或插入

            //判断设备编码有无重复
            String code = equipment.getCode();
            LambdaQueryWrapper<EquipmentManageDO> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(EquipmentManageDO::getCode, code);
            EquipmentManageDO exists = equipmentManageMapper.selectFirstOne(
                    EquipmentManageDO::getCode, code
            );

            if (exists != null) {
                //如果存在 判断是否允许更新
                if (isUpdateSupport) {
                    //允许更新
                    //设置ID
                    equipment.setId(exists.getId());
                    EquipmentManageDO updateEquipment = BeanUtils.toBean(equipment, EquipmentManageDO.class);
                    equipmentManageMapper.updateById(updateEquipment);
                    respVO.getUpdateNameList().add(equipment.getEquipmentName());
                } else {
                    //重复且不允许更新 标识为失败
                    respVO.getFailureMap().put(equipment.getEquipmentName(), EQUIPMENT_EXISTS.getMsg());
                }
            } else {
                //不存在 插入
                equipmentManageMapper.insert(BeanUtils.toBean(equipment, EquipmentManageDO.class));
                respVO.getInsertNameList().add(equipment.getEquipmentName());
            }
        });
        return respVO;
    }


    @Override
    public Long getEquipmentIdByCode(String code) {
        EquipmentManageDO equipment = equipmentManageMapper.selectFirstOne(
                EquipmentManageDO::getCode, code
        );
        if (equipment != null) {
            return equipment.getId();
        } else {
            throw exception(EQUIPMENT_MANAGE_NOT_EXISTS);
        }
    }


    public void setReVOName(EquipmentManageSaveReqVO reqVO) {
        DeptDO dept = deptService.getDept(reqVO.getDeptId());
        reqVO.setDeptName(dept.getName());
        Long equipmentClassify = reqVO.getEquipmentClassify();
        EquipmentTypeDO equipmentType = equipmentTypeService.getEquipmentType(equipmentClassify);
        reqVO.setEquipmentClassifyName(equipmentType.getName());
    }

    public void checkCodeExists(EquipmentManageSaveReqVO saveReqVO) {
        LambdaQueryWrapper<EquipmentManageDO> queryWrapper = new LambdaQueryWrapper<>();
        String code = saveReqVO.getCode();
        queryWrapper.eq(EquipmentManageDO::getCode, code);
        if (saveReqVO.getId() == null) {
            //新增 检查是否已存在设备编码
            if (equipmentManageMapper.exists(queryWrapper)) {
                throw exception(EQUIPMENT_EXISTS);
            }
        } else {
            //如果是修改操作 排除自身
            queryWrapper.ne(EquipmentManageDO::getId, saveReqVO.getId());
            if (equipmentManageMapper.exists(queryWrapper)) {
                throw exception(EQUIPMENT_EXISTS);
            }
        }

    }


    public void setUserName(EquipmentManageDO equipmentManageDO) {
        List<Long> respersonids = equipmentManageDO.getMaintenanceUserId();
        if (CollUtil.isNotEmpty(respersonids)) {
            List<AdminUserDO> users = userService.getUserList(respersonids);
            // 如果用户列表为空，抛出异常
            if (!users.isEmpty()) {
                // 将用户的姓名拼接成字符串
                String respersons = users.stream()
                        .map(AdminUserDO::getNickname)  // 获取用户姓名
                        .collect(Collectors.joining(", ")); // 使用逗号分隔
                // 设置到 createReqVO 中
                equipmentManageDO.setMaintenanceUserName(respersons);
            }
        }
    }

}